import React from 'react';
import {render} from 'react-dom';
import ReactAddons from 'react-addons';
import injectTapEventPlugin from 'react-tap-event-plugin';
import axios from 'axios';
import {browserHistory} from 'react-router';
import _ from 'lodash';
import Promise from 'bluebird';
//import Router from 'core/Router.js';
import config from './config.js';
import semantic from './semantic.js';
import utils from './utils.js';
import API from './api.js';
import URL from './url.js';
import Eventor from './Eventor.js';

class Application {
    constructor() {
        this._appDom = null;
        this._config = null;
        this.observe = null;
        this.LN = '';
        this.utils = utils;

    }

    define() {
        Object.defineProperty(this, 'config', {
            set: function(name) {
                return false;
            },
            get: () => {
                return this._config;
            }
        });

        return this;
    }

    _init({appDom, Router}) {
        this._Router = Router;
        this._appDom = appDom;
        this.gState = {};
        this.observers = {};
        this.storeObserver = {};
        this.eventor = {};
        this._config = config;
        this._routeParams = {};

        this.LN = '';
        this.SEM = semantic;
        this.rawAPI = API;
        this.rawURL = URL;

        this.define()
        .initEventor()
        .initLanguage()
        .then(() => {

            this.render();
            /*this.initConfig()
                .then(() => {


                });*/
            ////console.log(this.LN);
        });

        return this;
    }


    initEventor() {
        this.eventor = new Eventor();
        return this;
    }

    initConfig() {
        return axios.get(`/config/frontend.json`).then((res) => {
            var config;
            if (_.isString(res.data)) {
                config = eval('(' + res.data + ')');
            } else {
                config = res.data;
            }

            this._config = {...this._config, ...config};

            return config;

        });
    }

    initLanguage() {
        var lang = window.location.pathname.split('/')[1];
        if (~this._config.surportLanguages.indexOf(lang)) {
            if (this._config.language != lang) {

                this._config.language = lang;
            }
        } else {

            window.location.href = window.location.protocol + '//' + window.location.hostname + '/' + this._config.language;
            return Promise.reject();
        }


        return this.loadLanguage(this._config.language);

    }

    setRouteParams(params) {
        return this._routeParams = params;
    }

    getRouteParams() {
        return {...this._routeParams};
    }

    url(name, params, options = {}) {
        if (options.hostPrefix) {
            if (name == 'embedUrl') {
                return this._config.urlHost + this._config.embedUrlPrefix(this._config.language) + this.rawURL[name](params);
            }
            return this._config.urlHost + this._config.urlPrefix(this._config.language) + this.rawURL[name](params);
            // option condition
        } else {
            return this._config.urlPrefix(this._config.language) + this.rawURL[name](params);
        }
    }

    api(name, params, options) {
        if (!(options && options.type)) return this._config.apiHost + this._config.apiPrefixes[0] + this.rawAPI[name](params);
    }

    /*history.listenBeforeUnload(function () {
      return 'Are you sure you want to leave this page?'
    })*/


    loadLanguage(lang) {

        return axios.get(`/assets/lang/${this._config.mainLanguage}.lang`).then((res) => {
            //console.log(res);
            var mainLangObj;

            if (_.isString(res.data)) {
                mainLangObj = eval('(' + res.data + ')');
            } else {
                mainLangObj = res.data;
            }

            this.LN = mainLangObj;


            return mainLangObj;

        }).then((mainLangObj) => {
            let mixLangObj = mainLangObj;


            if (lang && (lang != this._config.mainLanguage)) {

                return axios.get(`/lang/${lang}.lang`).then((res) => {
                    //console.log(res);


                    if (_.isString(res.data)) {
                        mixLangObj = {...mainLangObj, ...eval('(' + res.data + ')')};
                    } else {
                        mixLangObj = {...mainLangObj, ...res.data};
                    }

                    this.LN = mixLangObj;
                    // this.LN = JSON.parse(res.data);
                    // this.LN = res.data;
                    // browserHistory.push(window.location.href);
                    //console.log(this.LN);
                    return res;
                });

            } else {

                return mixLangObj;
            }

        });


    }

    listen(name, func) {

        if (this.observers[name] && !(~this.observers[name].indexOf(func))) {
            this.observers[name].push(func);
        } else {
            this.observers[name] = [func];
        }
    }

    unlisten(name, func) {
        var index = this.observers[name].indexOf(func);
        if (this.observers[name] && (~index)) {
            this.observers[name].slice(index, 1);
        }
    }

    fire(name, ...rest) {
        if (this.storeObserver[name]) {
            this.storeObserver[name].forEach(fun => fun(...rest));
        } else {
            throw Error(name + ': this event is not exsited');
        }
    }


    // outside api
    setState(path, val) {

        //TODO
        /*
            path namespace rule for preventing mess state define by each dev
        */


        var arr = _.filter(path.split('/'), v => v);
        var now = this.gState;
        for (var i = 0, k = arr[i]; i < arr.length - 1; i++, k = arr[i]) {
            now = now[k];
            if (!now || !_.isObject(now)) {
                now[k] = {};
            } else {
                throw new Error(k + ': this key is exsit and not a object');
            }
        }

        now[arr[arr.length - 1]] = val;

        return this;

    }

    getState(path) {
        var arr = _.filter(path.split('/'), v => v);
        var now = this.gState;
        for (var i = 0, k = arr[i]; i < arr.length; i++, k = arr[i]) {
            now = now[k];
            if (!now || !_.isObject(now)) {
                now[k] = {};
            } else {
                throw new Error(k + ': this key is exsit and not a object');
            }
        }

        return this;
    }


    setConfig(conf) {
        this._config = _.extend(this._config, conf);
        if (conf.language) {
            this.loadLanguage(this._config.language);
        }

        return this;
    }


    //first render
    render() {

        injectTapEventPlugin();
        var Router = this._Router;
        if (!this._appDom.innerHTML) {
            render(<Router/>, this._appDom);
        }

        return this;
    }


}

export default Application;
